package concurrency.chapter9;

import java.util.stream.Stream;

//25讲-多Produce多Consume之间的通讯导致出现程序假死的原因分析[超清版]

/**
 * 没有死锁，
 */
public class ProduceConsumerVersion2 {
    private int i = 0;
    final private Object LOCK = new Object();
    private volatile boolean isProduced = false;

    private void produce() {
        synchronized (LOCK) {
            if (isProduced) {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                i++;
                System.out.println("P->" + i);
                LOCK.notify();
                isProduced = true;
            }

        }
    }

    private void consume() {
        synchronized (LOCK) {
            if (isProduced) {
                System.out.println("C->" + i);
                LOCK.notify();
                isProduced = false;
            } else {
                try {
                    LOCK.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        ProduceConsumerVersion2 pc = new ProduceConsumerVersion2();
        Stream.of("P1").forEach(n -> new Thread() {
        //Stream.of("P1", "P2").forEach(n -> new Thread() {
            @Override
            public void run() {
                while (true)
                    pc.produce();
            }
        }.start());
        Stream.of("C1").forEach(n -> new Thread() {
        //Stream.of("C1", "C2").forEach(n -> new Thread() {
            @Override
            public void run() {
                while (true)
                    pc.consume();
            }
        }.start());
    }
}
